﻿using HybridCLR;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using UniFramework.Machine;
using UnityEngine;
using YooAsset;

public static class FsmHotUpdateDLLLoad
{
    private static List<string> AOTMetaAssemblyFiles { get; } = new List<string>()
    {
        "mscorlib.dll",
        "System.dll",
        "System.Core.dll",
    };

    private static Assembly _hotUpdateAss;

    public static void LoadHotUpdateDll()
    {
        //LoadMetadataForAOTAssemblies();
#if !UNITY_EDITOR
        var loadHandle = YooAssets.LoadAssetSync<TextAsset>("HotUpdate.dll");
        byte[] dllBytes = (loadHandle.AssetObject as TextAsset).bytes;
        _hotUpdateAss = Assembly.Load(dllBytes);
        loadHandle.Release();
#else
        _hotUpdateAss = System.AppDomain.CurrentDomain.GetAssemblies().First(a => a.GetName().Name == "HotUpdate");
#endif
        // 切换到主页面场景
        SceneEventDefine.ChangeToHomeScene.SendEventMessage();
    }
    /// <summary>
    /// 为aot assembly加载原始metadata， 这个代码放aot或者热更新都行。
    /// 一旦加载后，如果AOT泛型函数对应native实现不存在，则自动替换为解释模式执行
    /// </summary>
    private static void LoadMetadataForAOTAssemblies()
    {
        /// 注意，补充元数据是给AOT dll补充元数据，而不是给热更新dll补充元数据。
        /// 热更新dll不缺元数据，不需要补充，如果调用LoadMetadataForAOTAssembly会返回错误
        /// 
        HomologousImageMode mode = HomologousImageMode.SuperSet;
        foreach (var aotDllName in AOTMetaAssemblyFiles)
        {
            var loadHandle = YooAssets.LoadAssetSync<TextAsset>(aotDllName);
            byte[] dllBytes = (loadHandle.AssetObject as TextAsset).bytes;
            // 加载assembly对应的dll，会自动为它hook。一旦aot泛型函数的native函数不存在，用解释器版本代码
            LoadImageErrorCode err = RuntimeApi.LoadMetadataForAOTAssembly(dllBytes, mode);
            Debug.Log($"LoadMetadataForAOTAssembly:{aotDllName}. mode:{mode} ret:{err}");
            loadHandle.Release();
        }
    }

}
